package com.lge.clock.worldclock.util;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import com.lge.clock.worldclock.cities.CityInformation;

import android.util.Log;

/**
 * @author lge.com
 */
public class IndexedListUtil 
{
	@SuppressWarnings("unused")
	private static final String TAG = "IndexListUtil";

	public static final int TYPE_CHAR_HANGUL_SYLLABLES = 0;
	public static final int TYPE_CHAR_HANGUL_JAMO = 1;
	public static final int TYPE_CHAR_ALPHABET = 2;
	
	private static final String SYMBOL_TYPED_CHAR = "Σ";
	private static final String SYMBOL_LEAST_CHAR = "@";
	private static final String SYMBOL_MOST_CHAR = "~";
	private static final int SYMBOL_LEAST = -1;
	private static final int SYMBOL_NONE = 0;
	private static final int SYMBOL_MOST = 1;
	
	private static final String SMALLER_BOUNDARY_ALPHABET = "\u0040";
	private static final String LARGER_BOUNDARY_ALPHABET = "\u007B";
	private static final String SMALLER_BOUNDARY_HANGUL = "\u3130";
	private static final String LARGER_BOUNDARY_HANGUL = "\u314F";
	
	private static final String[] HANGUL_JAMO_TOKENS = {
		"\u0000", "\u3131", "\u3134", "\u3137", "\u3139", "\u3141", "\u3142", "\u3145",
		"\u3147", "\u3148", "\u314A", "\u314B", "\u314C", "\u314D", "\u314E", "\uFFFF",
	};
	/*
	 * @, ?? ?? ?? ?? ?? ?? ??
	 * ?? ?? ?? ?? ?? ?? ?? ~.
	 */
	private static final String[] HANGUL_SYL_TOKENS = {
		"\uAC00", "\uB098", "\uB2E4", "\uB77C", "\uB9C8", "\uBC14", "\uC0AC", "\uC544",
		"\uC790", "\uCC28", "\uCE74", "\uD0C0", "\uD30C", "\uD558", "\uD7A4", "\uFFFF",
	};
	
	private static List<String> token_list = new LinkedList<String>();
	private static HashMap<Integer, String> pos_map = new HashMap<Integer, String>();

	
	/**
	 * 
	 * 
	 * @param cursor
	 * @param type HANGUL_SYLLABLES, HANGUL_JAMO, ALPHABET
	 * @return
	 */
//	public static HashMap<String, Integer> getPositionMap(
//			List<CityInformation> list, boolean hasTypedText)
//	{
//		clearTokenLists();
//		
//		if (list == null || list.isEmpty())
//		{
//			return null;
//		}
//
//		HashMap<String, Integer> map = new HashMap<String, Integer>();
//		boolean hasLeastSymbol = false;
//		boolean hasMostSymbol = false;
//		String crnt_token = null;
//		String prev_token = null;
//		int crnt_pos = -1;
//		int LANGUAGE_TYPE = TYPE_CHAR_HANGUL_SYLLABLES;
//		
//		if(CityInformation.getLanguageMode() == CityInformation.LANGUAGE_MODE_ENGLISH) {
//		    LANGUAGE_TYPE = TYPE_CHAR_ALPHABET;
//		}
//		
//		// TODO: should be tuned up for performance.
//		for (int i = 0; i < list.size(); i++)
//		{
//			switch (LANGUAGE_TYPE)
//			{
//				case TYPE_CHAR_HANGUL_SYLLABLES:
//					crnt_token = list.get(i).getKoreanCityName().substring(0, 1);
//					crnt_token = getHangulJamoToken(crnt_token);
//					break;
//				default:
//					crnt_token = list.get(i).getEnglishCityName().substring(0, 1);
//					break;
//			}
//			
//			if(crnt_token == null) {
//				return null;
//			}
//			
//			crnt_pos = i;
//			if (crnt_pos == 0 && hasTypedText)
//			{
//				prev_token = crnt_token;
//				map.put(SYMBOL_TYPED_CHAR, crnt_pos);
//				token_list.add(SYMBOL_TYPED_CHAR);
//				pos_map.put(crnt_pos, SYMBOL_TYPED_CHAR);
//			}
//			else
//			{
//				if (!hasLeastSymbol || !hasMostSymbol)
//				{
//					switch (getSymbolType(crnt_token, LANGUAGE_TYPE))
//					{
//						case SYMBOL_LEAST:
//							if (!hasLeastSymbol) 
//							{
//								prev_token = crnt_token;
//								hasLeastSymbol = true;
//								map.put(SYMBOL_LEAST_CHAR, crnt_pos);
//								token_list.add(SYMBOL_LEAST_CHAR);
//								pos_map.put(crnt_pos, SYMBOL_LEAST_CHAR);
//							}
//							break;
//						case SYMBOL_MOST:
//							if (!hasMostSymbol)
//							{
//								prev_token = crnt_token;
//								hasMostSymbol = true;
//								map.put(SYMBOL_MOST_CHAR, crnt_pos);
//								token_list.add(SYMBOL_MOST_CHAR);
//								pos_map.put(crnt_pos, SYMBOL_MOST_CHAR);
//							}
//							break;
//						case SYMBOL_NONE:
//							break;
//					}
//				}
//			}
//			
//			if (!crnt_token.equals(prev_token))
//			{
//				map.put(crnt_token, crnt_pos);
//				token_list.add(crnt_token);
//				pos_map.put(crnt_pos, crnt_token);
//			}
//			
//			prev_token = crnt_token;
//		}
//		
//		return map;
//	}

	public static String getHangulJamoToken(String syl_token)
	{
		if (syl_token == null) return null;
	
		for (int i = 0; i < HANGUL_SYL_TOKENS.length; i++)
		{
			if (syl_token.compareTo(HANGUL_SYL_TOKENS[i]) < 0)
			{
				return HANGUL_JAMO_TOKENS[i];
			}
		}
		
		return null;
	}
	
	public static List<String> getTokenList()
	{
		return token_list;
	}
	
	public static HashMap<Integer, String> getPosMap()
	{
		return pos_map;
	}

	public static int getSymbolType(String token, int type)
	{
		if (token == null || token.length() == 0) return SYMBOL_NONE;
		
		switch (type)
		{
			case TYPE_CHAR_ALPHABET:
				return getTokenTypeForAlphabet(token);
			case TYPE_CHAR_HANGUL_JAMO:
			case TYPE_CHAR_HANGUL_SYLLABLES:
				return getTokenTypeForHangul(token);
			default:
				return -1;
		}
	}
	
	private static int getTokenTypeForAlphabet(String token)
	{
		if (token.compareTo(SMALLER_BOUNDARY_ALPHABET) <= 0)
		{
			return SYMBOL_LEAST;
		}
		else if (token.compareTo(LARGER_BOUNDARY_ALPHABET) >= 0)
		{
			return SYMBOL_MOST;
		}
		else
		{
			return SYMBOL_NONE;
		}
	}
	
	private static int getTokenTypeForHangul(String token)
	{
		if (token.compareTo(SMALLER_BOUNDARY_HANGUL) <= 0)
		{
			return SYMBOL_LEAST;
		}
		else if (token.compareTo(LARGER_BOUNDARY_HANGUL) >= 0)
		{
			return SYMBOL_MOST;
		}
		else
		{
			return SYMBOL_NONE;
		}
	}
	
	private static void clearTokenLists()
	{
		if (token_list != null)
		{
			token_list.clear();
		}
		
		if (pos_map != null)
		{
			pos_map.clear();
		}
	}

	public static boolean isHangul(String word)
	{
		final String token = (word.length() > 1) ? word.substring(0, 1) : word;
	
		if ((token.compareTo(HANGUL_JAMO_TOKENS[1]) >= 0)
			&& (token.compareTo(HANGUL_JAMO_TOKENS[14]) <= 0)) {
			return true;
		}
		else {
			return false;
		}
	}
	
	public static boolean isEnglish(String word) {
		byte[] bytes = word.getBytes();
    	if(bytes.length > 0 && ((65 <= bytes[0] && bytes[0] <= 90)
    			|| (97 <= bytes[0] && bytes[0] <= 122))){
            return true;
    	}
    	else {
    		return false;
    	}
	}
}
